from datetime import datetime, timedelta
from typing import Optional
from jose import JWTError, jwt
from passlib.context import CryptContext
from .config import settings

# 密码上下文，使用bcrypt算法
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

# 验证密码
def verify_password(plain_password: str, hashed_password: str) -> bool:
    # 验证明文密码与哈希密码是否匹配
    return pwd_context.verify(plain_password, hashed_password)

# 获取密码哈希
def get_password_hash(password: str) -> str:
    # 对密码进行哈希处理
    return pwd_context.hash(password)

# 创建访问令牌
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    # 复制数据
    to_encode = data.copy()
    # 设置过期时间
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        # 默认15分钟过期
        expire = datetime.utcnow() + timedelta(minutes=15)
    # 更新过期时间
    to_encode.update({"exp": expire})
    # 编码JWT
    encoded_jwt = jwt.encode(to_encode, settings.secret_key, algorithm=settings.algorithm)
    # 返回令牌
    return encoded_jwt

# 验证令牌
def verify_token(token: str):
    try:
        # 解码JWT
        payload = jwt.decode(token, settings.secret_key, algorithms=[settings.algorithm])
        # 获取用户名
        username: str = payload.get("sub")
        # 如果用户名为空，返回None
        if username is None:
            return None
        # 返回用户名
        return username
    except JWTError:
        # JWT错误，返回None
        return None